import java.util.LinkedList;
import java.util.ListIterator;


public class Chain extends Simulation{

	protected LinkedList<Node> badNodes = new LinkedList<Node>();
	
	public Chain(double bTotal, long tMax, double lambda, double mu, int nodesNum) {
		super(bTotal, tMax, lambda, mu, nodesNum);
	}

	@Override
	protected void addToBadList(Node node) {
		ListIterator<Node> iter = badNodes.listIterator();
		
		while(iter.hasNext()) {
			Node n = iter.next();
			
			if(n.relIdx >= node.relIdx) {
				iter.previous();
				iter.add(node);
				return;
			}
		}
		iter.add(node);
	}

	@Override
	public double makeNodesShift(double maxDistanceToRun) {

		if(badNodes.isEmpty()) return maxDistanceToRun;

		double maxSrcMove = bTotal - badNodes.getLast().relIdx;
		double srcMove = Math.min(maxSrcMove, maxDistanceToRun);

		//if srcMove is 0 - the system is stuck, no movement
		if(srcMove == 0) return 0;
		
		//move all bad nodes relIdx for  srcMove distance
		for(Node n : badNodes) {
			n.relIdx += srcMove;
		}
				
		ListIterator<Node> iter = badNodes.listIterator();
		
		//we know here that badLIst is not empty
		while(iter.hasNext()) {
			Node n = iter.next();
			makeLazyShift(n.id + 1, n.relIdx);
		}
		
		return srcMove;
	}

	private void makeLazyShift(int id, double relIdx) {
		while(id < allNodes.length && allNodes[id].relIdx < relIdx) {
			allNodes[id].relIdx = relIdx;
			++id;
		}
	}

	@Override
	protected void removeFromBadList(Node node) {
		ListIterator<Node> iter = badNodes.listIterator();	
		while(iter.hasNext()) {
			Node n = iter.next();
			if(n == node) {
				iter.remove();
				return;
			}
		}
	}
}
